package com.tencent.sr.iris.activity.common.util;

import cn.hutool.extra.spring.SpringUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.ParserContext;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.SpelCompilerMode;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;


/**
 * @author nixiaolin
 * @date 2020/8/5 11:58
 */
public abstract class SpelUtils extends com.tencent.sr.rmall.springbootstarter.utils.SpelUtils {

    /**
     * bean工厂解析器
     */
    private static final BeanFactoryResolver BEAN_FACTORY_RESOLVER;

    /**
     * 解析器
     */
    private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(
            new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, SpelUtils.class.getClassLoader()));

    private static final ParserContext PARSER_CONTEXT = new TemplateParserContext();

    static {
        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        BEAN_FACTORY_RESOLVER = new BeanFactoryResolver(applicationContext);
    }

    /**
     * 解析spel表达式
     *
     * @param key
     * @param rootObject
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T parse(String key, Object rootObject, Class<T> clazz) {
        StandardEvaluationContext context = new StandardEvaluationContext(rootObject);
        context.setBeanResolver(BEAN_FACTORY_RESOLVER);
        return EXPRESSION_PARSER.parseExpression(key, PARSER_CONTEXT).getValue(context, rootObject, clazz);
    }
}
